package com.zenithmind.task.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.utils.BeanCopyUtils;
import com.zenithmind.task.mapper.TaskCommentMapper;
import com.zenithmind.task.pojo.entity.TaskComment;
import com.zenithmind.task.pojo.query.TaskCommentQuery;
import com.zenithmind.task.pojo.vo.TaskCommentVO;
import com.zenithmind.task.service.TaskCommentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 任务评论服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TaskCommentServiceImpl extends ServiceImpl<TaskCommentMapper, TaskComment> implements TaskCommentService {

    private final TaskCommentMapper taskCommentMapper;

    @Override
    public PageResult<TaskCommentVO> getCommentPage(TaskCommentQuery query, String userId) {
        Page<TaskComment> page = new Page<>(query.getCurrent(), query.getSize());
        IPage<TaskComment> resultPage = this.baseMapper.getCommentPage(page, query, userId);
        List<TaskCommentVO> voList = resultPage.getRecords().stream()
                .map(comment -> BeanCopyUtils.copyBean(comment, TaskCommentVO.class))
                .collect(Collectors.toList());
        return PageResult.of(voList, resultPage.getTotal());
    }

    @Override
    public List<TaskCommentVO> getCommentTree(String taskId, String userId) {
        // 1. 找出所有根评论
        LambdaQueryWrapper<TaskComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskComment::getTaskId, taskId)
                .isNull(TaskComment::getParentId)
                .orderByDesc(TaskComment::getCreateTime);
        List<TaskComment> rootComments = list(wrapper);

        if (rootComments.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 转换为VO并递归查找子评论
        return rootComments.stream()
                .map(comment -> {
                    TaskCommentVO vo = BeanCopyUtils.copyBean(comment, TaskCommentVO.class);
                    vo.setChildren(findChildren(vo.getId(), userId));
                    return vo;
                })
                .collect(Collectors.toList());
    }

    private List<TaskCommentVO> findChildren(String parentId, String userId) {
        List<TaskComment> children = this.baseMapper.findChildren(parentId, userId);
        if (children.isEmpty()) {
            return Collections.emptyList();
        }
        // 递归查找子评论的子评论
        List<TaskCommentVO> voChildren = children.stream()
                .map(child -> BeanCopyUtils.copyBean(child, TaskCommentVO.class))
                .collect(Collectors.toList());

        voChildren.forEach(child -> child.setChildren(findChildren(child.getId(), userId)));
        return voChildren;
    }

    @Override
    public TaskCommentVO getCommentById(String id, String userId) {
        TaskComment comment = getById(id);
        if (comment == null) {
            return null;
        }
        return BeanCopyUtils.copyBean(comment, TaskCommentVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addComment(TaskComment comment, String userId) {
        comment.setCommenterId(userId);
        // TODO: 设置用户名
        // comment.setUserName(UserContext.getUsername());
        return save(comment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean replyComment(String parentId, String content, String replyToId, String userId) {
        TaskComment parentComment = getById(parentId);
        if(parentComment == null) {
            throw new BusinessException("父评论不存在");
        }
        TaskComment comment = new TaskComment();
        comment.setTaskId(parentComment.getTaskId());
        comment.setParentId(parentId);
        comment.setContent(content);
        comment.setReplyToId(replyToId);
        // TODO: set replyToName
        comment.setCommenterId(userId);
        // TODO: set userName
        return save(comment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateComment(TaskComment comment, String userId) {
        TaskComment existing = getById(comment.getId());
        if (existing == null) {
            throw new BusinessException("评论不存在");
        }
        if (!existing.getCommenterId().equals(userId)) {
            // 或者根据角色权限判断
            throw new BusinessException("无权修改该评论");
        }
        return updateById(comment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteComment(String id, String userId) {
        TaskComment existing = getById(id);
        if (existing == null) {
            return true; // 或者抛出异常
        }
        if (!existing.getCommenterId().equals(userId)) {
             // 或者根据角色权限判断
            throw new BusinessException("无权删除该评论");
        }
        // 逻辑删除或物理删除
        return removeById(id);
    }

    @Override
    public Boolean likeComment(String id, String userId) {
        // TODO: 实现点赞逻辑，例如使用Redis记录点赞关系，并更新评论的点赞数
        log.info("User {} liked comment {}", userId, id);
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Boolean unlikeComment(String id, String userId) {
        // TODO: 实现取消点赞逻辑
        log.info("User {} unliked comment {}", userId, id);
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Boolean pinComment(String id, String userId) {
        log.info("User {} pinned comment {}", userId, id);
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Boolean unpinComment(String id, String userId) {
        log.info("User {} unpinned comment {}", userId, id);
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public List<TaskCommentVO> getLatestComments(String taskId, Integer limit, String userId) {
        LambdaQueryWrapper<TaskComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskComment::getTaskId, taskId)
               .orderByDesc(TaskComment::getCreateTime)
               .last("LIMIT " + limit);
        List<TaskComment> comments = list(wrapper);
        return comments.stream()
                .map(comment -> BeanCopyUtils.copyBean(comment, TaskCommentVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public PageResult<TaskCommentVO> getUserComments(String userId, Integer pageNum, Integer pageSize) {
        TaskCommentQuery query = new TaskCommentQuery();
        query.setCommenterId(userId);
        query.setCurrent(pageNum);
        query.setSize(pageSize);
        return getCommentPage(query, userId);
    }

    @Override
    public Boolean addSystemLog(String taskId, String content, String operatorId) {
        TaskComment comment = new TaskComment();
        comment.setTaskId(taskId);
        comment.setContent(content);
        comment.setCommenterId(operatorId); // 可能是系统用户的ID
        return save(comment);
    }

    // ==================== 辅助方法 ====================

    /**
     * 获取评论类型文本
     */
    private String getCommentTypeText(Integer commentType) {
        switch (commentType) {
            case 1: return "普通评论";
            case 2: return "系统评论";
            case 3: return "状态变更评论";
            default: return "未知";
        }
    }
}
